"""
pip install pywebio pymongo dnspython pandas plotly
"""

import pywebio
from pywebio.input import (
    input,
    radio,
    input_group,
    PASSWORD,
    NUMBER,
)
from pywebio.output import (
    popup,
    toast,
    put_text,
    put_buttons,
    put_markdown,
    close_popup,
    put_loading,
    use_scope,
)
from pywebio.pin import put_input, pin
from pywebio.session import hold
from pymongo import MongoClient


def change_favicon():
    # Change favicon.ico
    pywebio.session.run_js(
        "$('head link[rel=icon]').attr('href', image_url)",
        image_url="https://www.python.org/static/favicon.ico",
    )


# Initial Popup message
def warning():
    popup("Terms of Service", [
        put_text("Access authorized for employees only. This system is monitored and uses cookies."),
        put_buttons(["Agree"], onclick=lambda _: close_popup())
    ])


# Connect to MongoDB
def login():
    credentials = input_group("MongoDB Portal", [
        input(
            label="Username",
            name="username",
        ),
        input(
            label="Password",
            name="password",
            type=PASSWORD,
            placeholder="Enter your password",
            help_text="Please contact IT Support for access.",
            required=True,
        ),
        radio(
            label="Environment",
            options=["PROD", "QA", "DEV"],
            value="PROD", inline=True,
            required=True, name="env",
        )
    ])

    with put_loading(shape="border", color="dark"):

        username = credentials.get("username")
        password = credentials.get("password")

        global env, db

        env = credentials.get("env")
        if env == "PROD":
            host = "db.prod.mongodb.net/"
        elif env == "QA":
            host = "db.qa.mongodb.net/"
        elif env == "DEV":
            host = "db.dev.mongodb.net/"

        # Auth database
        auth_database = "admin"

        uri = (f'mongodb://{username}:{password}@{host}/{auth_database}',)
        # 覆盖 uri 用于测试
        uri = f'mongodb://192.168.3.21'

        cluster = MongoClient(uri)

        database = "sample_analytics"
        db = cluster[database]

        collections = db.list_collection_names()


# Start session
def session(attempts=0):
    if attempts > 5:
        return put_markdown("# Not authorized!")
    try:
        login()
    except Exception as e:
        print(str(e))
        attempts += 1
        toast(
            content="Incorrect username, password, and environment combination.",
            color="error",
        )
        session(attempts)
    else:
        toast("Successfully connected to " + env, color="success")
        put_markdown("# MongoDB Portal")
        get_customers()


def get_customers():
    put_markdown("## Customer Lookup")
    put_input("accounts", type=NUMBER)
    put_buttons(["Lookup"], lambda _: lookup_accounts(pin.accounts))
    hold()


def lookup_accounts(account_number):
    with use_scope("search_result", clear=True):
        with put_loading(shape="border", color="dark"):
            customers = db.customers

            # Search pipeline for customers collection in MongoDB
            pipeline = [
                {
                    "$match": {
                        "$and": [{"accounts": account_number}, ]
                    }
                },
                # Show everything except _id field
                {"$project": {"_id": 0}}
            ]

            import pandas as pd
            data = pd.DataFrame(list(customers.aggregate(pipeline)))
            columns = data.columns.tolist()
            rows = data.values.tolist()

            # Show interactive data visualizations
            from pywebio.output import put_html
            import plotly.graph_objects as go

            fig = go.Figure(data=[
                go.Table(
                    header=dict(values=["Customer Info"]),
                    cells=dict(values=rows),
                )
            ])
            html = fig.to_html(include_plotlyjs="require", full_html=False)
            put_html(html)


def main():
    change_favicon()
    warning()
    session()


# ###################
# Webapp page flow #
# ###################
if __name__ == '__main__':
    # 进入脚本所在目录，用于测试
    import os
    from pathlib import Path
    os.chdir(Path(__file__).cwd())

    # 只执行一次。
    # main()

    # 放到 start_server 中循环执行，不退出。
    pywebio.start_server(
        applications=main,
        host='127.0.0.1',
        port=9090,
        auto_open_webbrowser=False,
    )
